feat(queue): guided 队列策略(运行中消息注入)+ SSE 阻塞读(流式实时化) - #1009
Conversation
|
Codex Review: 预 review 基于 发现 2 个会丢失用户输入的问题。
验证:该 head 独立快照执行 |
|
前者的逻辑已经在 steer 实现了,后者是性能和体验的取舍,目前(上游活跃 0.1s、空闲扩到 4s)的体验已经很好了。如果觉得可以优化,可以将退避上限调整为0.5s。 使用 Redis Streams XREAD BLOCK 会一直占用 SSE 连接,高用户场景下 SSE 资源会被占满。 |
|
感谢 review,两个丢失路径都成立,已修复(最新 head [P1] 让位即丢失 → 先判让位、不消费 guided确认: 修复:先判定 steer;命中即返回让位,完全不触碰 guided,请求保持 [P1] injected 早于 checkpoint → 以 checkpoint 为已生效判据做幂等重放确认: 修复:把
判据用 证据
未验证范围:没有做「提交 injected → 杀 worker 进程 → 重启续跑」的进程级故障注入 E2E;上面用真实 PostgreSQL 覆盖了持久化与恢复判定这一步。若你希望以进程级故障注入作为合并前提,我可以按 关于拆分:guided 与 SSE 阻塞读在 |
|
接受关闭,两个判断都成立,感谢说明。
关于「退避上限调整为 0.5s」:如果后续观察到空闲→活跃切换的迟滞,我会按这个方向单独提一个很小的轮询参数 PR,不再动阻塞读。 这个 PR 就不再推了,谢谢 review。 |
现象
智能体长任务运行中,两个体验痛点:
enqueue(排队等 Run 结束)和steer(结束当前 Run 让位)都覆盖不了「运行中补充一句修正,让它即时调整方向」——比如调研跑了 3 分钟补一句「只看 2024 年后文献」,期望它接着按新约束继续,而不是作废重来。对标
Claude Code 的两条核心交互:① 长任务运行中直接输入补充消息,任务不中断、模型下一轮按新约束继续;② 流式「来一个 token 显示一个」,几乎无感知延迟。这两条是「智能体好不好用」的分水岭。
机理
NOT_IMPLEMENTED_QUEUE_POLICIES = ("guided", "bridge")。SteerMiddleware挂了before_model钩子但只处理了steer,缺「运行中注入消息」路径。改进方法
guided 队列:
guided从NOT_IMPLEMENTED移入SUPPORTED_QUEUE_POLICIES,新增状态REQUEST_STATUS_INJECTED = "injected";SteerMiddleware.abefore_model调take_pending_guided_messages(run_id)把等待消息作为HumanMessage追加进 state 的messages,模型下一轮即看到,Run 不终止;raw_message恢复原始 id 按 id 去重;注入失败静默退化。SSE 阻塞读:
blocking_read_run_stream_events,用 Redis StreamsXREAD BLOCK:有事件毫秒级唤醒,无事件挂起最多 1s;保留after_seq游标续读语义,空闲零 CPU 空转。效果
运行中发补充消息,模型下一轮按新约束修正,前序成果不丢失;流式延迟从轮询间隔降到毫秒级,token 连续吐出。附 10 个 guided/steer 单测 + 4 个阻塞读单测 + 4 个 SSE 行为单测。